﻿namespace EFS.Common.Async
{
	/// <summary>
	/// Async process 
	/// </summary>
	public class AsyncException : EFS.Common.Async.AsyncRoot
	{
		#region Composition

		// exception
		private System.Exception exception = null;

		#endregion

		#region Delegates

		/// <summary>
		/// Exception method to call
		/// </summary>
		public delegate void AsyncExceptionHandler(System.Exception exception);

		/// <summary>
		/// Handler
		/// </summary>
		private AsyncExceptionHandler asyncExceptionHandler = null;

		#endregion

		#region Constructor

		/// <summary>
		/// Constructor
		/// </summary>
		internal AsyncException(System.Exception exception, AsyncExceptionHandler asyncExceptionHandler)
		{
			// root & work can not be null
			EFS.Common.Verify.Reference(exception, "exception");
			EFS.Common.Verify.Reference(asyncExceptionHandler, "asyncExceptionHandler");

			// keep 
			this.exception = exception;
			this.asyncExceptionHandler = asyncExceptionHandler;
		}

		#endregion

		#region Usage

		/// <summary>
		/// Describe this object into a nice formated string
		/// </summary>
		/// <returns></returns>
		public override System.String Describe()
		{
			return System.String.Format("EFS.Common.Async.AsyncException");
		}

		/// <summary>
		/// Unhandled exception
		/// </summary>
		/// <param name="ex"></param>
		protected override void OnException(System.Exception ex)
		{
			// check
			EFS.Common.Verify.Reference(ex, "ex");
#if !SILVERLIGHT
			// log
			EFS.EventLog.Log.LogException(ex, this);
#endif
		}

		/// <summary>
		/// Wait complete
		/// </summary>
		public void Execute()
		{
			// execute
			BeginAsyncProcess2(ExecuteExceptionHandler);
		}

		#endregion

		#region Runtime

		/// <summary>
		/// Execute exception handler
		/// </summary>
		private void ExecuteExceptionHandler()
		{
			try
			{
				// call handler safe
				asyncExceptionHandler(exception);
			}
#if !SILVERLIGHT
			catch (System.Exception ex)
			{
				// log both
				EFS.EventLog.Log.LogException(ex);
#else
			catch
			{	
#endif
			}
		}

		#endregion
	}
}